package com.meeting.meetingroom_api.service;

import com.meeting.meetingroom_api.dto.BookingDto;
import com.meeting.meetingroom_api.entity.Booking;
import com.meeting.meetingroom_api.enums.BookingStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.dao.OptimisticLockingFailureException;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
//TODO:待深度测试
@Service
public class BookingScheduledService {

    private final BookingService bookingService;
    private final int MAX_RETRIES = 3; // 最大重试次数
    private final Logger logger = LoggerFactory.getLogger(BookingScheduledService.class);

    public BookingScheduledService(BookingService bookingService) {
        this.bookingService = bookingService;
    }

    // 每2分钟执行一次补偿扫描
    @Scheduled(cron = "0 0/2 * * * *")
    public void checkOverdueBookings() {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime fiveMinutesAgo = now.minusMinutes(5);//范围包括前5分钟内

        List<Booking> overdueBookings = bookingService
                .findByStatusAndPaymentDeadlineBetween(
                        BookingStatus.pending_payment,
                        fiveMinutesAgo,
                        now
                );

        for (Booking booking : overdueBookings) {
            processOverdueBookingWithRetry(booking);
        }
    }

    // 每30分钟执行一次过期预订清理
    @Scheduled(cron = "0 */30 * * * *")
    public void cleanExpiredBookings() {
        try {
            logger.info("开始执行过期预订清理任务");
            bookingService.processExpiredBookings();
            logger.info("过期预订清理任务执行完成");
        } catch (Exception e) {
            logger.error("过期预订清理任务执行失败", e);
        }
    }

    @Transactional
    public void processOverdueBookingWithRetry(Booking booking) {
        int retries = 0;
        while (retries < MAX_RETRIES) {
            try {
                processOverdueBooking(booking);
                break;
            } catch (OptimisticLockingFailureException e) {
                retries++;
                logger.warn("Optimistic lock failure, 重试 ({}/{}): {}",
                        retries, MAX_RETRIES, booking.getBookingId());
                // 重新获取最新的Booking
                BookingDto bookingDto = bookingService.getTimeOutBookById(booking.getBookingId());
                if (bookingDto == null) {
                    logger.error("重试中,找到最新的booking订单: {}", booking.getBookingId());
                    break;
                }
            } catch (Exception e) {
                logger.error("Error processing overdue booking {}", booking.getBookingId(), e);
                break;
            }
        }

        if (retries >= MAX_RETRIES) {
            logger.error("Max retries reached for booking {}", booking.getBookingId());
            // 可以添加告警机制，通知管理员手动处理
        }
    }

    private void processOverdueBooking(Booking booking) {
        // 检查是否仍然超时
        if (booking.getPaymentDeadline().isBefore(LocalDateTime.now())) {
            bookingService.handleTimeOut(booking);
            logger.info("预订订单 {} 待支付超时取消", booking.getBookingId());
        }
    }

   /* @Transactional
    public void processOverdueBooking(Booking booking) {
        try {
            // 检查是否仍然超时
            if (booking.getPaymentDeadline().isBefore(LocalDateTime.now())) {
                //更新订单状态为payment_timeout
                bookingService.handleTimeOut(booking);
                logger.info("预订订单 {} 待支付超时取消", booking.getBookingId());
            }
        } catch (OptimisticLockingFailureException e) {
            logger.warn("Optimistic lock failure while processing booking {}", booking.getBookingId());
            // 可选择重试或记录日志
        } catch (Exception e) {
            logger.error("Error processing overdue booking {}", booking.getBookingId(), e);
        }
    }*/
}